﻿// See https://aka.ms/new-console-template for more information
//值类型struct，enum
//引用类型class，interface，delegate
//编译后，以上所有类型都会编译成class，当clr检测到你的类型继承了ValueType，则在栈上面分配内存，因此，继承了ValueType的则认为是值类型，反之则是引用类型
//接口的特殊情况，接口没有基类，但是他可以把引用类型赋值给接口，实际上调用的是引用类型里的东西，所以接口不能单独存在，不能new
//string是特殊的引用类型，他是不可变类型，每次给变量赋值都是重写开辟内存空间赋值，把引用传递给原来的变量，同时相同字面量的string类型变量，指向的同一块内存空间

Console.WriteLine(typeof(int).BaseType);
Console.WriteLine("Hello, World!");
string a = "123";
string b = "123";
Console.WriteLine(a == b);

var result = QueryCityData("New York City");
var city = result.Item1;
var pop = result.Item2;
var size = result.Item3;
Console.WriteLine(city);
Console.WriteLine(pop);
Console.WriteLine(size);

//析构元组的使用
(string city1,int pop1,double area1)= QueryCityData("New York City");
var (city2,pop2,area2)= QueryCityData("New York City");
(var city3,var pop3,var area3)= QueryCityData("New York City");
var p = new Person("John","Quincy","Adams","Boston","MA");
var (obj1, obj2) = p;
Console.WriteLine(obj1);
Console.WriteLine(obj2);
var (obj3, obj4, obj5) = p;
Console.WriteLine(obj3);
Console.WriteLine(obj4);
Console.WriteLine(obj5);


(string, int, double) QueryCityData(string name)
{
    if (name == "New York City")
        return (name, 8175133, 468.48);

    return ("", 0, 0);
}

internal class test
{
    //vs快捷生成的构造函数
    //public test(string name, string descrption)
    //{
    //    this.name = name;
    //    this.descrption = descrption;
    //}

    //上下等同
    //以元组形式实现的对类的属性赋值
    public test(string name, string descrption) => (this.name, this.descrption) = (name, descrption);

    public string name { get; set; }
    public string descrption { get; set; }
}

//类型的析构元组自定义
class Person
{
    public Person(string firstName, string middleName, string lastName, string city, string state)
    {
        FirstName = firstName;
        MiddleName = middleName;
        LastName = lastName;
        City = city;
        State = state;
    }

    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; } 
    public string City { get; set; }
    public string State { get; set; }

    //Deconstruct百度翻译析构
    //类型定义Deconstruct方法并且参数列表全为输出类型参数,那么在类型实例化之后就可以用元组接受值
    //自定义析构元组函数
    public void Deconstruct(out string fname,out string lname)
    {
        fname = FirstName;
        lname = LastName;
    }

    //自定义析构元组函数
    public void Deconstruct(out string fname,out string mname, out string lname)
    {
        fname = FirstName;
        mname = MiddleName;
        lname = LastName;
    }
}